package main

import (
	"github.com/kataras/iris"
	"time"
	"github.com/ngaut/log"
	"global/structs"
	"server/ote/model"
	"github.com/shopspring/decimal"
)

// 添加交易对
func onAddCoinPair(ctx iris.Context) {

	coinPair := ctx.URLParam("coin_pair")
	if coinPair == "" {
		ApiError(ctx, ERR_COINPAIR_NOT_EXISTS)
		return
	}

	if ote.CheckCoinPiarWorking(coinPair) {
		log.Errorf("coin pair is working")
		ApiSuccess(ctx, "success")
		return
	}

	item, err := model.CoinPairModel.GetFirst(coinPair)
	if err != nil {
		log.Errorf("get coin pair error, msg: %s", err.Error())
		ApiError(ctx, ERR_COINPAIR_NOT_EXISTS)
		return
	}

	// check item
	if item.Enabled != model.COIN_PAIR_ENABLED {
		log.Errorf("coin pair status not correct, enabled: %s", item.Enabled)
		ApiError(ctx, ERR_COINPAIR_CONF_NOT_RIGHT)
		return
	}

	buyRate, _ := decimal.NewFromString(item.TradeBuyRate)
	saleRate, _ := decimal.NewFromString(item.TradeSaleRate)

	if buyRate.GreaterThanOrEqual(decimal.NewFromFloat(1)) || saleRate.GreaterThanOrEqual(decimal.NewFromFloat(1)) {
		log.Errorf("coin pair rate must below 1, buy rate: %s, sale rate: %s", item.TradeBuyRate, item.TradeSaleRate)
		ApiError(ctx, ERR_COINPAIR_CONF_NOT_RIGHT)
		return
	}

	w := NewWorker(ote, *item)
	w.Start()
	ote.RegistWorker(item.Name, w)
	log.Infof("start listening coin pair [%s] success ...", item.Name)

	ote.Data.AddCoinPiar(*item)

	ApiSuccess(ctx, "success")
}

// 获取服务器基本信息
func onInfoRequest(ctx iris.Context) {
	c := ote.Configuration
	info := structs.ServBaseInfo{
		Name: 		c.App.Name,
		Ip: 		c.Http.Ip,
		Port: 		c.Http.Port,
		LogOn: 		c.Log.On,
		Duration: 	time.Since(ote.startTime).String(),
	}
	ApiSuccess(ctx, info)
}

// 服务器状态
func onGetStatusHandler(ctx iris.Context) {

	type item struct {
		CoinPair 		string			`json:"coin_pair"`
		QueueNumber		int 			`json:"queue_number"`
		Status			WorkerStatus	`json:"status"`
		ResultLength 	int 			`json:"result_length"`
		IsBuyWorking 	bool 			`json:"is_buy_working"`
		IsSaleWorking 	bool 			`json:"is_sale_working"`
		IsCancelWorking bool 			`json:"is_cancel_working"`
		CancelResultLength int 			`json:"cancel_result_length"`
		Duration 		string 			`json:"duration"`
	}

	workers := make([]item, 0)
	for k, w := range ote.workers {

		var duration string
		if w.status == WORK_STATUS_RUNNING {
			duration = time.Since(w.startTime).String()
		} else {
			duration = time.Since(w.stopTime).String()
		}

		workers = append(workers, item{
			CoinPair: 				k,
			QueueNumber: 			w.GetQueueNumbers(),
			Status: 				w.status,
			IsBuyWorking: 			w.isTaskBuyWorking,
			IsSaleWorking: 			w.isTaskSaleWorking,
			IsCancelWorking: 		w.isTaskCancelWorking,
			ResultLength: 			0,
			Duration: 				duration,
		})
	}

	ApiSuccess(ctx, workers)
}

// 停止服务
func onStopHandler(ctx iris.Context) {
	coinPair := ctx.URLParam("coin_pair")
	worker, ok := ote.workers[coinPair]
	if !ok {
		ApiError(ctx, ERR_COINPAIR_NOT_EXISTS)
		return
	}

	if worker.status == WORK_STATUS_RUNNING {
		// 不能销毁此实例，因为还有撮单任务还在执行
		worker.Stop()
	}

	ApiSuccess(ctx, map[string]interface{}{
		"status": worker.status,
	})
}

// 一键起停
func onSystemctlAll(ctx iris.Context) {
	ctlType := ctx.URLParam("ctl_type")
	if ctlType != "start" && ctlType != "stop" {
		ApiSuccess(ctx, ERR_CTL_TYPE)
		return
	}

	for _, w := range ote.workers {
		if ctlType == "start" {
			w.Restart()
			if w.isRun() {
				log.Infof("[%s] get restarted success", w.coinPair.Name)
			} else {
				log.Errorf("[%s] get restarted failed", w.coinPair.Name)
			}
		} else {
			w.Stop()
			if w.isRun() {
				log.Errorf("[%s] get stop failed", w.coinPair.Name)
			} else {
				log.Infof("[%s] get stop success", w.coinPair.Name)
			}
		}
	}

	ApiSuccess(ctx, nil)
}

// 开启服务
func onStartHandler(ctx iris.Context) {
	coinPair := ctx.URLParam("coin_pair")
	worker, ok := ote.workers[coinPair]
	if ok {
		worker.Restart()
		log.Infof("restart listening coin pair [%s] success ...", coinPair)
	} else {
		// rebuild coin pair data
		ote.Data.GetCoinPair()
		has, item := ote.Data.GetOne(coinPair)
		if !has {
			ApiError(ctx, ERR_COINPAIR_NOT_EXISTS)
			return
		}

		w := NewWorker(ote, item)
		w.Start()
		ote.RegistWorker(coinPair, w)
		log.Infof("start listening coin pair [%s] success ...", coinPair)
	}

	ApiSuccess(ctx, nil)
}

// add or remove user no fee list
// type: string "add", "remove"
// uid: int
func onSetIsNoFee(ctx iris.Context) {
	setType := ctx.URLParam("type")
	uid, _ := ctx.URLParamInt("uid")
	if (setType != "add" && setType != "remove") || uid <= 0 {
		ApiError(ctx, ERR_PARAMS)
		return
	}

	user, err := model.UserModel.GetUserByUID(uid)
	if err != nil || user == nil || user.Uid <= 0 {
		ApiError(ctx, ERR_USER_NOT_FOUND)
		return
	}

	if user.Uid == OFFICIAL_UID {
		ApiError(ctx, ERR_USER_CANNOT_REMOVE)
		return
	}

	if setType == "remove" {
		ote.Data.RemoveNoFeeUser(uid)
	} else {
		ote.Data.AddNoFeeUser(uid)
	}

	ApiSuccess(ctx, uid)
}
